home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / cgazv5n5.arc / EVENT.C < prev    next >
C/C++ Source or Header  |  1991-09-23  |  17KB  |  533 lines

  1. /***************************************************************
  2.  * File:     Event.c -
  3.  * Purpose:  Starts routines or macros at an arbitrary time
  4.  * Author:   Kanhom Ng
  5.  *           P.O. Box 391176, Mountain View, CA 94039
  6.  *
  7.  * Compiler: Microsoft C 6.00a
  8.  *
  9.  * Source code may be used freely if source is acknowledged.
  10.  * Object code may be used freely.
  11.  **************************************************************/
  12.  
  13. #define NOCOMM
  14. #include <windows.h>
  15.  
  16. #include <stdio.h>
  17. #include <memory.h>
  18. #include <string.h>
  19. #include <time.h>
  20. #include <ctype.h>
  21. #include "event.h"
  22.  
  23. #define ID_LISTBOX    1000   /* id of the list box */
  24. #define MAX_EVENT     20     /* maximum event allowed */
  25. #define Date2Str(t,s) \
  26.           wsprintf( s, "%d/%d/%d", (t).tm_mon + 1, \
  27.           (t).tm_mday, (t).tm_year )
  28. #define Time2Str(t,s) \
  29.           wsprintf( s, "%d:%.2d", (t).tm_hour, (t).tm_min )
  30. #define Str2Date(s,t) \
  31.           ( 3 == sscanf( s, "%d/%d/%d", &((t).tm_mon), \
  32.           &((t).tm_mday), &((t).tm_year) ) && (t).tm_mon-- )
  33. #define Str2Time(s,t) \
  34.           ( 2 == sscanf( s, "%d:%d", &((t).tm_hour), \
  35.           &((t).tm_min) ) )
  36.  
  37. /* global variables */
  38. static  EVENTREC  aEventList[ MAX_EVENT ];  /* event list */
  39. static  int       anDateFirstTabStop[2]
  40.                     = { 48, 100 };    /* list box's tab stops */
  41. static  PEVENTREC pEventRec; /* dummy dialog box parameter */
  42.  
  43. /* function prototypes */
  44. LONG FAR PASCAL EventCenterWndProc( HWND, WORD, WORD, LONG );
  45. BOOL FAR PASCAL _export EventDlgProc( HWND, WORD, WORD, LONG );
  46. HANDLE PASCAL SpawnApp( LPSTR    lpszCmdLine );
  47.  
  48. /*
  49.  * WinMain( hInstance, hPrevInst, lpszCmd ) : int;
  50.  *
  51.  * This is the entry point for the Event application
  52.  *
  53.  */
  54. int PASCAL WinMain(
  55.     HANDLE          hInstance,
  56.     HANDLE          hPrevInst,
  57.     LPSTR           lpszCmd,
  58.     WORD            wCmdShow )
  59. {
  60.  
  61.     MSG      msg;       /* MSG Structure for message loop */
  62.     HWND     hwndEvent; /* handle to the windows */
  63.     WNDCLASS WndClass;  /* WNDCLASS structure */
  64.  
  65.     if ( hPrevInst == 0 ) {
  66.         _fmemset( &WndClass, 0, sizeof( WndClass ) );
  67.  
  68.         WndClass.lpfnWndProc = EventCenterWndProc;
  69.         WndClass.hInstance = hInstance;
  70.         WndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  71.         WndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
  72.         WndClass.hbrBackground = ( COLOR_APPWORKSPACE + 1 );
  73.         WndClass.lpszMenuName = "CenterMain";
  74.         WndClass.lpszClassName = "EventCenter";
  75.  
  76.         RegisterClass( &WndClass );
  77.     }
  78.     hwndEvent = CreateWindow(
  79.                   "EventCenter",
  80.                   "Event Scheduler",
  81.                   WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  82.                   CW_USEDEFAULT, CW_USEDEFAULT,
  83.                   CW_USEDEFAULT, CW_USEDEFAULT,
  84.                   NULL, NULL, hInstance, NULL );
  85.     ShowWindow( hwndEvent, wCmdShow );
  86.  
  87.     /* main message loop */
  88.     while ( GetMessage( &msg, NULL, 0, 0 ) ) {
  89.         TranslateMessage( &msg );
  90.         DispatchMessage( &msg );
  91.     }
  92.     return ( NULL );
  93. }
  94.  
  95. /*
  96.  * EventCenterWndProc( hwndEvent, wMessage, wParam, lParam ) : LONG;
  97.  *
  98.  *
  99.  * This is the window function for Event's Main window.
  100.  */
  101. LONG FAR PASCAL EventCenterWndProc(
  102.     HWND           hwndEvent,
  103.     WORD           wMessage,
  104.     WORD           wParam,
  105.     LONG           lParam
  106.     )
  107. {
  108.  
  109.     BOOL    fSuccess;    /* were we successful? */
  110.     LONG    lReturn;     /* return value of this function */
  111.     HANDLE  hInstance;   /* handle to the instance */
  112.     HWND    hwndRecorder;/* handle to Recorder's main window */
  113.     RECT    rc;          /* current window client rect */
  114.     int     i, j;        /* loop variables */
  115.     int     iSel;        /* index to the current selection */
  116.     int     cEvent;      /* count of the event */
  117.     int     cString;     /* string # in Recorder's listbox */
  118.     char    szText[240]; /* temporary text string */
  119.     char    szTime[20];  /* temporary string for time */
  120.     char    szDate[20];  /* temporary string for date */
  121.     FARPROC lpfnEvent;   /* event dialog box function */
  122.     struct  tm tmCurTime;/* current time */
  123.     time_t  lCurTime;    /* current time */
  124.     time_t  lEventTime;  /* time specified in the event record */
  125.  
  126.     /* initialization */
  127.     lReturn = 0L;
  128.     fSuccess = FALSE;
  129.  
  130.     switch ( wMessage ) {
  131.     case WM_CREATE:
  132.         /* create a listbox window to display all events */
  133.         CreateWindow(
  134.             "listbox", NULL,
  135.             LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | WS_CHILD |
  136.              WS_VISIBLE | LBS_USETABSTOPS,
  137.             0, 0, 0, 0,
  138.             hwndEvent, ID_LISTBOX,
  139.             GetWindowWord( hwndEvent, GWW_HINSTANCE ), NULL );
  140.  
  141.         /* initialize the tab stop for the listbox */
  142.         SendDlgItemMessage( hwndEvent, ID_LISTBOX,
  143.             LB_SETTABSTOPS, 2, (LONG)(LPINT)anDateFirstTabStop);
  144.  
  145.         /* initialize the timer */
  146.         SetTimer( hwndEvent, 1, 5000, NULL );
  147.  
  148.         /* initialize the array of events */
  149.         _fmemset( aEventList, 0, sizeof( aEventList ) );
  150.  
  151.         /* send self a WM_TIMER message to update title */
  152.         PostMessage(hwndEvent, WM_TIMER, 0, 0L);
  153.         break;
  154.  
  155.     case WM_DESTROY:
  156.         KillTimer( hwndEvent, 1 );
  157.         PostQuitMessage(0);
  158.         break;
  159.  
  160.     case WM_TIMER:
  161.         /* retrieve count of # of pending events */
  162.         cEvent = (int) SendDlgItemMessage( hwndEvent,
  163.                     ID_LISTBOX, LB_GETCOUNT, 0, 0l );
  164.  
  165.         /* retrieve the current time adjusted for local time */
  166.         lCurTime = time( NULL );
  167.         tmCurTime = *localtime( &lCurTime );
  168.         lCurTime = mktime( &tmCurTime );
  169.  
  170.         /* update window's title bar with current time */
  171.         wsprintf(szText, "Event Scheduler: %02d:%02d:%02d",
  172.             tmCurTime.tm_hour,
  173.             tmCurTime.tm_min,
  174.             tmCurTime.tm_sec);
  175.         SetWindowText(hwndEvent, szText);
  176.  
  177.         for ( i = 0; i < cEvent; i ++ )
  178.         {
  179.             /* Should this event be executed at this time? */
  180.             if (FALSE == aEventList[ i ].fCalled
  181.                 && (lEventTime = mktime( &aEventList[ i ].tm))
  182.                 && (lEventTime != -1 && lEventTime <= lCurTime))
  183.             {
  184.                 aEventList[i].fCalled = TRUE;
  185.                 SpawnApp( aEventList[ i ].szCmd );
  186.  
  187.                 /* need to replay a macro ? */
  188.                 if ( aEventList[ i ].fRecorder )
  189.                 {
  190.                     /* spawn Recorder with the specified file */
  191.                     SpawnApp( aEventList[ i ].szFile );
  192.                     hwndRecorder = FindWindow("recorder", NULL);
  193.                     if ( hwndRecorder )
  194.                     {
  195.                         /* retrieve count of string in
  196.                            Recorder's list box */
  197.                         cString = (int)SendDlgItemMessage(
  198.                           hwndRecorder, 60, LB_GETCOUNT, 0, 0l);
  199.  
  200.                         /* find our macro in the listbox */
  201.                         for ( j = 0; j < cString; j++ )
  202.                         {
  203.                             /* retrieve the string text from
  204.                              * the listbox and compare it with
  205.                              * the user's macro name. */
  206.                             fSuccess = SendDlgItemMessage(
  207.                                 hwndRecorder, 60, LB_GETTEXT,
  208.                                 j, (LONG)(LPSTR)szText ) >= 0;
  209.                             /* is it our macro? when checking
  210.                              * the name, must skip over the TAB
  211.                              * that Recorder places before the
  212.                              * macro's name. Thus, we compare to
  213.                              * szText[1], not szText[0]. */
  214.                             if ( fSuccess && lstrcmpi(
  215.                                 &szText[1],
  216.                                 aEventList[ i ].szMacro ) == 0 )
  217.                             {
  218.                                 /* select this string in the
  219.                                  * listbox and send a message
  220.                                  * that runs the macro. */
  221.                                 SendDlgItemMessage(hwndRecorder,
  222.                                     60, LB_SETCURSEL, j, 0L );
  223.                                 SendMessage( hwndRecorder,
  224.                                     WM_COMMAND, 0x0011, 0L );
  225.                                 /* shut down recorder */
  226.                                 SendMessage( hwndRecorder,
  227.                                     WM_COMMAND, 0x000E, 0L );
  228.                                 break;
  229.                             }
  230.                         }
  231.                     }
  232.                 }
  233.             }
  234.         }
  235.         break;
  236.  
  237.     case WM_SIZE: /* make sure our list box fits */
  238.         GetClientRect( hwndEvent, &rc );
  239.         MoveWindow( GetDlgItem( hwndEvent, ID_LISTBOX ),
  240.             rc.left, rc.top, rc.right - rc.left,
  241.             rc.bottom - rc.top, TRUE );
  242.         break;
  243.  
  244.     case WM_SETFOCUS: /* let the listbox have the focus */
  245.         SetFocus( GetDlgItem( hwndEvent, ID_LISTBOX ) );
  246.         break;
  247.  
  248.     case WM_INITMENU:   /* gray the Delete if no event is
  249.                            currently selected */
  250.         iSel = (int)SendDlgItemMessage( hwndEvent, ID_LISTBOX,
  251.             LB_GETCURSEL, 0, 0l );
  252.         EnableMenuItem( GetMenu( hwndEvent ), IDM_DELETE,
  253.             iSel >= 0 ? MF_ENABLED : MF_GRAYED );
  254.         break;
  255.  
  256.     case WM_COMMAND:
  257.         switch ( wParam )
  258.         {
  259.         case IDM_NEW:
  260.             cEvent = (int)SendDlgItemMessage( hwndEvent,
  261.                 ID_LISTBOX, LB_GETCOUNT, 0, 0l );
  262.             if ( cEvent < MAX_EVENT )
  263.             {
  264.                 /* initialization */
  265.                 _fmemset( &aEventList[ cEvent ], 0,
  266.                     sizeof( aEventList[ cEvent ] ) );
  267.                 hInstance = GetWindowWord( hwndEvent,
  268.                     GWW_HINSTANCE );
  269.                 lpfnEvent = MakeProcInstance(
  270.                     (FARPROC)EventDlgProc, hInstance );
  271.                 pEventRec = &aEventList[ cEvent ];
  272.  
  273.                 if (-1 != DialogBox( hInstance, "Event",
  274.                             hwndEvent, lpfnEvent )
  275.                         && Time2Str( aEventList[ cEvent ].tm,
  276.                             szTime )
  277.                         && Date2Str( aEventList[ cEvent ].tm,
  278.                             szDate ) )
  279.                 {
  280.                     /* format the event into a string
  281.                      * and add to our listbox */
  282.                     wsprintf(szText, "%s\t%s\t%s",
  283.                         (LPSTR)szDate, (LPSTR)szTime,
  284.                         (LPSTR)aEventList[ cEvent ].szDesc );
  285.                     SendDlgItemMessage( hwndEvent,
  286.                         ID_LISTBOX, LB_ADDSTRING, 0,
  287.                         (LONG)(LPSTR)szText );
  288.                 }
  289.  
  290.                 FreeProcInstance( lpfnEvent );
  291.             }
  292.             break;
  293.  
  294.         case IDM_DELETE:
  295.             iSel = (int)SendDlgItemMessage( hwndEvent,
  296.                 ID_LISTBOX, LB_GETCURSEL, 0, 0l );
  297.             cEvent = (int)SendDlgItemMessage( hwndEvent,
  298.                 ID_LISTBOX, LB_GETCOUNT, 0, 0l );
  299.             SendDlgItemMessage( hwndEvent, ID_LISTBOX,
  300.                 LB_DELETESTRING, iSel, 0l );
  301.  
  302.             /* move the remaining slot 1 up */
  303.             _fmemcpy( &aEventList[ iSel ],
  304.                 &aEventList[ iSel + 1 ],
  305.                 sizeof(aEventList[iSel]) * (cEvent - iSel - 1));
  306.             break;
  307.  
  308.         case IDM_EXIT:
  309.             DestroyWindow( hwndEvent );
  310.             break;
  311.  
  312.         }
  313.         break;
  314.  
  315.     default:
  316.         lReturn = DefWindowProc( hwndEvent, wMessage,
  317.                                  wParam, lParam );
  318.         break;
  319.     }
  320.  
  321.     return ( lReturn );
  322. }
  323.  
  324. /*
  325.  * EventDlgProc( hwndDlg, wMessage, wParam, lParam ) : BOOL;
  326.  *
  327.  *    This is the function for the NEW dialog box.
  328.  *
  329.  */
  330. BOOL FAR PASCAL _export EventDlgProc(
  331.     HWND           hwndDlg,
  332.     WORD           wMessage,
  333.     WORD           wParam,
  334.     LONG           lParam
  335.     )
  336. {
  337.  
  338.     BOOL      fReturn;    /* return value of this function */
  339.     char      szTime[40]; /* temporary string for the time */
  340.     char      szDate[40]; /* temporary string for the date */
  341.     time_t    lTime;      /* current time value */
  342.     struct tm tm;         /* structure for the time functions */
  343.  
  344.     /* initialization */
  345.     fReturn = TRUE;
  346.  
  347.     switch ( wMessage )
  348.     {
  349.     case WM_INITDIALOG:
  350.         /* initilize the Date and Time
  351.            field to be current date and time */
  352.         lTime = time( NULL );
  353.         tm = *localtime( &lTime );
  354.         Time2Str( tm, szTime );
  355.         Date2Str( tm, szDate );
  356.         SetDlgItemText( hwndDlg, ID_TIME, szTime );
  357.         SetDlgItemText( hwndDlg, ID_DATE, szDate );
  358.         break;
  359.  
  360.     case WM_COMMAND:
  361.         switch ( wParam )
  362.         {
  363.         case IDOK:
  364.             /* 1. use the time()/localtime() to fill
  365.              *      out tm_isdst (daylight saving time)
  366.              * 2. retrieve the date and time from the user
  367.              */
  368.             lTime = time( NULL );
  369.             tm = *localtime( &lTime );
  370.             tm.tm_sec = 0;
  371.             GetDlgItemText( hwndDlg, ID_DATE, szDate,
  372.                 sizeof( szDate ) );
  373.             GetDlgItemText( hwndDlg, ID_TIME, szTime,
  374.                 sizeof( szTime ) );
  375.  
  376.             /* did the user specify a valid date and time ? */
  377.             if ( Str2Date( szDate, tm ) && Str2Time(szTime, tm))
  378.             {
  379.                 /* retrieve the description and command line */
  380.                 GetDlgItemText( hwndDlg, ID_DESC,
  381.                     pEventRec->szDesc,
  382.                     sizeof( pEventRec->szDesc ) );
  383.                 GetDlgItemText( hwndDlg, ID_CMDLINE,
  384.                     pEventRec->szCmd,
  385.                     sizeof( pEventRec->szCmd ) );
  386.  
  387.                 /* retrieve whether to replay a macro,
  388.                    and the file and the macro name */
  389.                 pEventRec->fRecorder = IsDlgButtonChecked(
  390.                     hwndDlg, ID_RUNRECORDER );
  391.                 GetDlgItemText( hwndDlg, ID_FILE,
  392.                     pEventRec->szFile,
  393.                     sizeof( pEventRec->szFile ) );
  394.                 GetDlgItemText( hwndDlg, ID_MACRONAME,
  395.                     pEventRec->szMacro,
  396.                     sizeof( pEventRec->szMacro ) );
  397.  
  398.                 pEventRec->tm = tm;
  399.                 EndDialog( hwndDlg, TRUE );
  400.             }
  401.             else {
  402.                 SHOWERR( FALSE, hwndDlg,
  403.                     "Incorrect date or time specified");
  404.             }
  405.             break;
  406.  
  407.         case IDCANCEL:
  408.             EndDialog( hwndDlg, -1 );
  409.             break;
  410.         }
  411.         break;
  412.  
  413.     default:
  414.         fReturn = FALSE;
  415.         break;
  416.     }
  417.  
  418.     return ( fReturn );
  419. }
  420.  
  421. /*
  422.  * SpawnApp( lpszCmdLine ) : VOID;
  423.  *
  424.  * This function will spawn an application.  It looks up the
  425.  * win.ini extension section to insert the proper parameter
  426.  * before calling WinExec(). as WinExec() will only take care
  427.  * of the standard extensions .exe and .pif.
  428.  *
  429.  */
  430. HANDLE PASCAL SpawnApp(
  431.     LPSTR                lpszCmdLine
  432.     )
  433. {
  434.     BOOL    fSuccess;        /* did we succeed? */
  435.     char    szAppName[ 160]; /* build command line here */
  436.     char    *p;              /* temporary pointer */
  437.     char    *pDot;           /* temporary pointer to '.' + 1 */
  438.     HANDLE  hModule;         /* handle to the loaded module */
  439.     char    szExt[4];        /* extension string */
  440.     HCURSOR hOldCursor;      /* handle to the old cursor */
  441.  
  442.     /* Change to waiting cursor */
  443.     hOldCursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) );
  444.  
  445.     /* copy the app name and parameter */
  446.     lstrcpy( szAppName, lpszCmdLine );
  447.     szAppName[ sizeof( szAppName ) -1 ] = 0;
  448.  
  449.     /* find out where the parameters start */
  450.     p = strchr( szAppName, ' ' );
  451.  
  452.     /* Are there any parameters at all? */
  453.     if ( NULL == p )
  454.     {
  455.         /* no parameters, therefore it could be an extension */
  456.  
  457.         /* find the extension */
  458.         pDot = strchr( szAppName, '.' );
  459.  
  460.         if ( pDot )
  461.         {
  462.             /* Is this a standard extension? */
  463.             if (_fstrnicmp( pDot + 1, "exe", 3 ) == 0
  464.                 ||  _fstrnicmp( pDot + 1, "pif", 3 ) == 0 )
  465.             {
  466.                 /* standard WINDOWS extension */
  467.                 /* which WinExec() will handle */
  468.             }
  469.             else { /* nonstandard extension */
  470.                 /* extract the extension */
  471.                 _fstrncpy( szExt, pDot + 1, 3 );
  472.                 szExt[ 3 ] = 0;
  473.  
  474.                 /* try to find the [Extension] in win.ini
  475.                  * to figure out which application will
  476.                  * handle this extension */
  477.                 fSuccess = GetProfileString(
  478.                       "Extensions", szExt, "",
  479.                       szAppName, sizeof( szAppName ) ) > 0
  480.                     &&  lstrcmp( szAppName, "" ) != 0;
  481.  
  482.                 /* Correct extension specified in win.ini ? */
  483.                 if ( fSuccess )
  484.                 {
  485.                     /* now the szAppName should look like this:
  486.                      * "notepad.exe ^.txt"
  487.                      */
  488.  
  489.                     /* find out where the parameters start */
  490.                     p = strchr( szAppName, ' ' );
  491.  
  492.                     /* expected format ? */
  493.                     if  ( p )
  494.                     {
  495.                         /* cut off the parameters */
  496.  
  497.                         *( p + 1 ) = 0;
  498.  
  499.                         /* now szAppName looks like this:
  500.                         * "notepad.exe "
  501.                         */
  502.                     }
  503.                     else
  504.                     {
  505.                         /* UNexpected format */
  506.  
  507.                         /* clean all the junk */
  508.                         szAppName[ 0 ] = 0;
  509.                     }
  510.                 }
  511.  
  512.                 /* append the Original Spawn statement to the
  513.                  * end of the proper application name. */
  514.                 _fstrncat( szAppName, lpszCmdLine,
  515.                     sizeof( szAppName ) );
  516.  
  517.                 /* ensure it is NULL-terminated */
  518.                 szAppName[ sizeof( szAppName ) - 1 ] = 0;
  519.             }
  520.         }
  521.     }
  522.  
  523.     hModule = WinExec( szAppName, SW_SHOW );
  524.     hModule = ( hModule < 32 ) ? hModule : 0;
  525.  
  526.     /* Change back to original */
  527.     if ( hOldCursor )
  528.     {
  529.         SetCursor( hOldCursor );
  530.     }
  531.  
  532.     return ( hModule );
  533. }